pub mod llm;
pub mod sql_gen;
pub mod analysis;

pub use llm::{LlmProvider, LlmResponse};
pub use sql_gen::{SqlGenerator, GeneratedSql};
pub use analysis::{DataAnalyzer, AnalysisResult};

use anyhow::Result;
use tracing::info;

/// AI engine for database management
#[derive(Debug)]
pub struct AiEngine {
    llm_provider: LlmProvider,
    sql_generator: SqlGenerator,
    data_analyzer: DataAnalyzer,
}

impl AiEngine {
    /// Create a new AI engine
    pub async fn new() -> Result<Self> {
        info!("Initializing AI engine");

        let llm_provider = LlmProvider::new().await?;
        let sql_generator = SqlGenerator::new();
        let data_analyzer = DataAnalyzer::new();

        Ok(Self {
            llm_provider,
            sql_generator,
            data_analyzer,
        })
    }

    /// Create a new AI engine synchronously
    pub fn new_sync() -> Self {
        info!("Initializing AI engine (sync)");

        let llm_provider = LlmProvider::new_sync();
        let sql_generator = SqlGenerator::new();
        let data_analyzer = DataAnalyzer::new();

        Self {
            llm_provider,
            sql_generator,
            data_analyzer,
        }
    }
    
    /// Generate SQL from natural language
    pub async fn generate_sql(&self, prompt: &str, schema_context: Option<&str>) -> Result<GeneratedSql> {
        info!("Generating SQL from prompt: {}", prompt);
        self.sql_generator.generate(prompt, schema_context).await
    }
    
    /// Analyze query performance
    pub async fn analyze_query(&self, sql: &str) -> Result<AnalysisResult> {
        info!("Analyzing query performance");
        self.data_analyzer.analyze_query(sql).await
    }
    
    /// Get AI response for general questions
    pub async fn chat(&self, message: &str, context: Option<&str>) -> Result<LlmResponse> {
        info!("Processing AI chat message");
        self.llm_provider.chat(message, context).await
    }
    
    /// Explain SQL query
    pub async fn explain_sql(&self, sql: &str) -> Result<String> {
        info!("Explaining SQL query");
        self.llm_provider.explain_sql(sql).await
    }
    
    /// Optimize SQL query
    pub async fn optimize_sql(&self, sql: &str) -> Result<String> {
        info!("Optimizing SQL query");
        self.sql_generator.optimize(sql).await
    }
}

impl Default for AiEngine {
    fn default() -> Self {
        Self::new_sync()
    }
}

#[cfg(test)]
mod tests;
